package main

import (
	"encoding/json"
	"log"
	"net/http"
)

type response struct {
	Ok    bool     `json:"ok"`
	ID    string   `json:"id,omitempty"`
	Error string   `json:"error,omitempty"`
	IDs   []string `json:"ids,omitempty"`
	Task  *task    `json:"task,omitempty"`
}

// handle tasks
func taskHandle(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case http.MethodPost:
		w.Header().Set("Content-Type", "application/json")
		t := new(task)
		err := json.NewDecoder(r.Body).Decode(t)
		if err != nil {
			log.Printf("add task err: %s\n", err.Error())

			data, _ := json.Marshal(response{
				Ok:    false,
				Error: "invalid task.",
			})
			w.Write(data)
			return
		}

		resp := response{}
		if err = _Tasks.Add(t); err != nil {
			w.WriteHeader(409)
			resp.Error = err.Error()
		} else {
			resp.Ok, resp.ID = true, t.ID
		}

		data, _ := json.Marshal(resp)
		w.Write(data)
	case http.MethodGet:
		w.Header().Set("Content-Type", "application/json")
		id := r.FormValue("id")
		t := _Tasks.Get(id)
		if t == nil {
			w.WriteHeader(404)
			w.Write([]byte(`{"ok":false,"error":"The task [` + id + `] is not found."}`))
			return
		}

		data, _ := json.Marshal(response{
			Ok:   true,
			Task: t,
		})
		w.Write(data)
	case http.MethodDelete:
		w.Header().Set("Content-Type", "application/json")
		t := new(task)
		err := json.NewDecoder(r.Body).Decode(t)
		if err != nil {
			log.Printf("del task err: %s\n", err.Error())

			data, _ := json.Marshal(response{
				Ok:    false,
				Error: "invalid data.",
			})
			w.Write(data)
			return
		}

		resp := response{}
		if err = _Tasks.Del(t.ID); err != nil {
			w.WriteHeader(404)
			resp.Error = err.Error()
		} else {
			resp.Ok, resp.ID = true, t.ID
		}

		data, _ := json.Marshal(resp)
		w.Write(data)
	}
}

// list tasks
func listHandle(w http.ResponseWriter, r *http.Request) {
	ids := _Tasks.List()
	if len(ids) == 0 {
		w.Header().Set("Content-Type", "application/json")
		w.Write([]byte(`{"ok":false}`))
		return
	}

	data, err := json.Marshal(response{
		Ok:  true,
		IDs: ids,
	})
	if err != nil {
		log.Printf("[ERR] %s\n", err.Error())
		w.WriteHeader(500)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(data)
}
